/*
 * \ * Copyright 2006-2015 Transsion.com All right reserved. This software is the confidential and proprietary
 * information of Transsion.com ("Confidential Information"). You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license agreement you entered into with Transsion.com.
 */
package com.yunji.framework_template.common.redis;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * ClassName:RedisHelper <br/>
 * Date: 2015年7月16日 下午5:39:17 <br/>
 * 
 * @author fenglibin
 * @version
 * @see
 */
@Component("redisHelper")
public class RedisHelper implements InitializingBean {

    private static Logger                 logger = Logger.getLogger(RedisHelper.class);

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Value("#{settings['current.system.name']}")
    private String                        systemName;

    /**
     * 压栈
     * 
     * @param key
     * @param value
     * @return
     */
    public Long leftPush(String key, String value) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * 出栈
     * 
     * @param key
     * @return
     */
    public String leftPop(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().leftPop(key);
    }

    /**
     * 入队
     * 
     * @param key
     * @param value
     * @return
     */
    public Long rightPush(String key, String value) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * 出队
     * 
     * @param key
     * @return
     */
    public String rightPop(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().rightPop(key);
    }

    /**
     * 栈/队列长
     * 
     * @param key
     * @return
     */
    public Long size(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().size(key);
    }

    /**
     * 范围检索
     * 
     * @param key
     * @param start
     * @param end
     * @return
     */
    public List<String> range(String key, int start, int end) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().range(key, start, end);
    }

    /**
     * 移除key中值为value的i个,返回删除的个数；如果没有这个元素则返回0
     * 
     * @param key
     * @param i
     * @param value
     */
    public long remove(String key, long i, String value) {
        return redisTemplate.opsForList().remove(key, i, value);
    }

    /**
     * 检索
     * 
     * @param key
     * @param index
     * @return
     */
    public String index(String key, long index) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForList().index(key, index);
    }

    /**
     * 置值
     * 
     * @param key
     * @param index
     * @param value
     */
    public void set(String key, long index, String value) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.opsForList().set(key, index, value);
    }

    /**
     * 裁剪
     * 
     * @param key
     * @param start
     * @param end
     */
    public void trim(String key, long start, int end) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.opsForList().trim(key, start, end);
    }

    /**
     * 将给定的Key的值增加指定的值
     * 
     * @param key
     * @param delta
     * @return 增加指定值后的值
     */
    public long incrment(String key, long delta) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForValue().increment(key, delta);

    }

    /**
     * 将给定的Key的值增加指定的值
     * 
     * @param key
     * @param delta
     * @return 增加指定值后的值
     */
    public double incrment(String key, double delta) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 将给定的Key的值增加1
     * 
     * @param key
     * @return 增加1后的值
     */
    public long incr(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.getConnectionFactory().getConnection().incr(key.getBytes());

    }

    /**
     * 设值
     * 
     * @param key
     * @param value
     */
    public void set(String key, String value) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.opsForValue().set(key, value);

    }

    /**
     * 设值
     * 
     * @param key
     * @param value
     * @param timeout 指定过期的时间
     */
    public void set(String key, String value, long timeout) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        set(key, value, timeout, TimeUnit.SECONDS);

    }

    /**
     * 设值
     * 
     * @param key
     * @param value
     * @param timeout 指定数据过期的时间
     * @param timeUnit 数据过期的时间单位
     */
    public void set(String key, String value, long timeout, TimeUnit timeUnit) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);

    }

    /**
     * 如果不存在该，则增加该key
     * 
     * @param key
     * @param value
     */
    public void setIfAbsent(String key, String value) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    /**
     * 取值
     * 
     * @param key
     * @return
     */
    public String get(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 从redis队尾中读取内容
     * 
     * @param queenName
     * @return
     */
    public String getLastFromQueen(String queenName) {
        try {
            byte[] results = redisTemplate.getConnectionFactory().getConnection().rPop(queenName.getBytes());
            if (results == null || results.length == 0) {
                return null;
            }
            return (String) redisTemplate.getValueSerializer().deserialize(results);
        } catch (Exception e) {
            logger.error("Get data from redis queen " + queenName + " exception happened.", e);
        }
        return null;
    }

    /**
     * 从队列的头，插入
     */
    public void pushFromHead(String queenName, String value) {
        redisTemplate.boundListOps(queenName).leftPush(value);
    }

    /**
     * 设值
     * 
     * @param key
     * @param value
     */
    public void delete(String key) {
        key = new StringBuilder(systemName).append("_").append(key).toString();
        redisTemplate.delete(key);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (systemName == null) {
            throw new RuntimeException("The config parameter current.system.name is empty or not exists.");
        }

    }
}
